using AutoMapper;
using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Read.Api.Application.Command.Medical;
using static RBAC.Read.Api.Application.Command.Medical.GetDoctorScheduleListCommand;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using static S.O.ErrorCode.APIEnums;
using S.O.Interstructrue.Base;

namespace RBAC.Read.Api.Application.Handler.Medical
{
    /// <summary>
    /// 获取医生排班列表处理器
    /// </summary>
    public class GetDoctorScheduleListHandler : IRequestHandler<GetDoctorScheduleListCommand, APIResult<List<DoctorScheduleDto>>>
    {
        private readonly IBaseRepository<DoctorScheduleModel> _scheduleRepository;
        private readonly IMapper _mapper;
        private readonly ILogger<GetDoctorScheduleListHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="scheduleRepository">医生排班仓储</param>
        /// <param name="mapper">映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetDoctorScheduleListHandler(
            IBaseRepository<DoctorScheduleModel> scheduleRepository,
            IMapper mapper,
            ILogger<GetDoctorScheduleListHandler> logger)
        {
            _scheduleRepository = scheduleRepository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取医生排班列表请求
        /// </summary>
        /// <param name="request">请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>医生排班列表</returns>
        public async Task<APIResult<List<DoctorScheduleDto>>> Handle(GetDoctorScheduleListCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始获取医生排班列表，医生ID: {DoctorId}, 科室ID: {DepartmentId}, 排班日期: {ScheduleDate}, 时间段: {TimeSlot}",
                    request.DoctorId, request.DepartmentId, request.ScheduleDate, request.TimeSlot);

                // 构建查询条件
                var query = _scheduleRepository.GetALL().Where(s => !s.IsDeleted);

                // 按医生ID筛选
                if (request.DoctorId.HasValue)
                {
                    query = query.Where(s => s.DoctorId == request.DoctorId.Value);
                }

                // 按科室ID筛选（暂时跳过，因为模型中没有DepartmentId属性）
                // if (request.DepartmentId.HasValue)
                // {
                //     query = query.Where(s => s.DepartmentId == request.DepartmentId.Value);
                // }

                // 按排班日期筛选
                if (request.ScheduleDate.HasValue)
                {
                    query = query.Where(s => s.ScheduleDate.Date == request.ScheduleDate.Value.Date);
                }

                // 按时间段筛选
                if (!string.IsNullOrEmpty(request.TimeSlot))
                {
                    query = query.Where(s => s.TimeSlot == request.TimeSlot);
                }

                // 按排班日期和时间段排序
                query = query.OrderBy(s => s.ScheduleDate).ThenBy(s => s.StartTime);

                // 执行查询
                var schedules = query.ToList();

                // 转换为DTO
                var dtoList = schedules.Select(s => new DoctorScheduleDto
                {
                    Id = (int)s.Id,
                    DoctorId = (int)s.DoctorId,
                    DoctorName = s.DoctorName,
                    DepartmentId = 0, // 暂时设为0，因为模型中没有DepartmentId
                    DepartmentName = s.Department,
                    ScheduleDate = s.ScheduleDate,
                    TimeSlot = s.TimeSlot,
                    StartTime = s.StartTime,
                    EndTime = s.EndTime,
                    MaxRegistrations = s.MaxRegistrations,
                    CurrentRegistrations = s.CurrentRegistrations,
                    ScheduleStatus = s.Status,
                    Remarks = s.Remarks,
                    HasAvailableSlots = s.HasAvailableSlots
                }).ToList();

                _logger.LogInformation("成功获取医生排班列表，共 {Count} 条记录", dtoList.Count);

                return new APIResult<List<DoctorScheduleDto>>
                {
                    Code = Success,
                    Msg = "获取医生排班列表成功",
                    Data = dtoList
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取医生排班列表时发生错误");
                return new APIResult<List<DoctorScheduleDto>>
                {
                    Code = Fail,
                    Msg = "获取医生排班列表失败",
                    Data = null!
                };
            }
        }
    }
}